<template>
  <!--
  element全部引入，所以不需要引入注册组件了～
  -->
  <el-card class="trademark">
    <!-- 默认插槽 -->
    <el-button
      v-if="$hasBtnPermission('btn.Trademark.add')"
      type="primary"
      @click="showAddTrademark"
    >
      添加品牌
    </el-button>
    <!--
      el-table 表格组件
        data：数据（表格要渲染的数据）
        border: 边框
    -->
    <el-table :data="trademarkList" border class="trademark-table">
      <!--
        el-table-column 表格的列（表格要渲染几列）
          prop 渲染data数据中的某项数据
          label 列头（表头显示的内容）
          width 宽度
          type="index" 显示序号（从1开始）
          align="center" 居中显示
      -->
      <el-table-column type="index" label="序号" width="50" align="center" />
      <el-table-column prop="tmName" label="品牌名称" />
      <el-table-column label="品牌LOGO">
        <template v-slot="{ row }">
          <img :src="row.logoUrl" :alt="row.tmName" class="trademark-img" />
        </template>
      </el-table-column>
      <!-- <el-table-column prop="address" label="操作" /> -->
      <el-table-column label="操作" width="200">
        <!--
          默认情况下，列渲染的就是prop对应的值，只能是纯文本
          想要渲染其他结构（图片、按钮），就需要插槽语法
          使用默认插槽和作用域插槽
            v-slot="{ row }"
              row就是当前行数据
        -->
        <template v-slot="{ row }">
          <el-button
            v-if="$hasBtnPermission('btn.Trademark.update')"
            type="warning"
            size="small"
            icon="el-icon-edit"
            @click="showUpdateTrademark(row)"
          >
            修改
          </el-button>
          <el-button
            v-if="$hasBtnPermission('btn.Trademark.remove')"
            type="danger"
            size="small"
            icon="el-icon-delete"
            @click="delTrademark(row)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!--
      对话框组件
        title 标题
        :visible.sync
          .sync 父子组件双向通信（传递一个props和自定义事件用来修改数据）
     -->
    <el-dialog
      :title="`${trademarkForm.id ? '修改' : '添加'}品牌`"
      :visible.sync="visible"
    >
      <!-- 默认插槽：作为内容区展示 -->
      <!--
        el-form 表单
          model 整个表单的数据（将来表单校验时会读取里面的数据进行校验）
          rules 整个表单的校验规则
            对某个表单项生效，配合prop一起使用
            prop指定的规则名，这个表单项使用这个规则
          ref 获取真实DOM元素或组件实例对象
            给组件绑定，获取的就是组件实例对象
            获取el-form的实例对象，将来通过这个实例对象就可以使用一些表单的方法
              组件实例对象上面有一些方法
                validate 表单校验的方法
                clearValidate 清空表单校验
          label-width label文字的宽度
        el-form-item 单个表单项
       -->
      <el-form
        ref="formRef"
        :model="trademarkForm"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="品牌名称" prop="tmName">
          <el-input v-model="trademarkForm.tmName" />
        </el-form-item>
        <el-form-item label="品牌LOGO" prop="logoUrl">
          <!--
            上传图片组件
              action 上传服务器地址（看接口文档）
                /admin/product/fileUpload
                  不对，他会向http://localhost:9528发送请求，
                  本地开发服务器并不能处理上传图片请求
                正确写法：
                  1. 写完整服务器地址：http://39.98.123.211/admin/product/fileUpload
                  2. 写代理服务器地址：/dev-api/admin/product/fileUpload
                    会向代理服务器发送请求，由代理服务器转发请求到目标服务器去
              show-file-list 是否展示上传文件列表（是否可以上传多张图片）
              on-success 上传成功触发的函数
              before-upload 上传之前触发的函数
                对上传的文件的大小和类型进行限制
          -->
          <el-upload
            class="avatar-uploader"
            action="/dev-api/admin/product/fileUpload"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img
              v-if="trademarkForm.logoUrl"
              :src="trademarkForm.logoUrl"
              class="avatar"
            />
            <i v-else class="el-icon-plus avatar-uploader-icon" />
          </el-upload>
          <p>只能上传jpg/png文件，且不超过500kb</p>
        </el-form-item>
      </el-form>
      <!-- 使用命名插槽：给组件的底部传递标签数据 -->
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="visible = false">取 消</el-button>
          <el-button type="primary" @click="addTrademark">确 定</el-button>
        </span>
      </template>
    </el-dialog>
    <!--
      el-pagination 分页器
        @size-change 自定义事件，当pageSize发生变化时，触发的事件
        @current-change 自定义事件，当currentPage发生变化时，触发的事件
        current-page 当前页码（第几页）
        page-size 每页条数（每页渲染多少条数据）
        page-sizes 每页条数可选项
        layout 分页器要加载的组件情况
    -->
    <el-pagination
      :current-page="currentPage"
      :page-sizes="[3, 6, 9, 12]"
      :page-size="pageSize"
      layout="prev, pager, next, jumper, total, sizes"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </el-card>
</template>

<script>
// import { mapState } from 'vuex'
// 引入接口函数
import {
  getTrademarkList,
  addTrademark,
  updateTrademark,
  delTrademark
} from '@/api/product/trademark'

export default {
  name: 'Trademark',
  data() {
    return {
      // 表格数据
      trademarkList: [],
      // 当前页码
      currentPage: 1,
      // 每页条数
      pageSize: 3,
      // 总数
      total: 0,
      // 对话框显示&隐藏
      visible: false,
      // 保证命名要一致
      // 表单数据
      trademarkForm: {
        // 品牌名称
        tmName: '',
        // 品牌LOGO
        logoUrl: ''
      },
      // 表单验证规则
      rules: {
        // 里面key就是规则名称，规则名称必须和数据名称一致
        tmName: [
          {
            required: true, // 必填项
            message: '请输入品牌名称', // 错误提示信息
            trigger: 'blur' // 触发验证时机：失去焦点
          }
        ],
        logoUrl: [
          {
            required: true, // 必填项
            message: '请上传品牌LOGO', // 错误提示信息
            trigger: 'blur' // 触发验证时机：失去焦点
          }
        ]
      }
    }
  },
  // computed: {
  //   ...mapState('user', ['buttons'])
  // },
  // 以上来就需要数据展示，在mounted发送
  mounted() {
    this.getTrademarkList()
  },
  methods: {
    // 删除品牌
    delTrademark(row) {
      this.$confirm(
        `您确认要删除 <strong class="trademark-text">${row.tmName}</strong> 品牌吗?`,
        '删除',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          dangerouslyUseHTMLString: true // 才能使用html
        }
      )
        .then(async () => {
          // 发送请求，删除服务器的数据
          await delTrademark(row.id)
          // 发送请求，更新客户端数据
          this.getTrademarkList()

          this.$message({
            type: 'success',
            message: '删除成功!'
          })
        })
        .catch(() => {
          // this.$message({
          //   type: 'info',
          //   message: '已取消删除'
          // })
        })
    },
    // 显示修改品牌
    showUpdateTrademark(row) {
      // console.log(row)
      this.visible = true
      // 将当前行数据更新到data中，数据就会渲染到页面上
      // row中有一个id属性的
      // this.trademarkForm = row // 同一个对象，操作trademarkForm时会修改row的数据
      this.trademarkForm = { ...row } // 生成全新的对象
      // this.trademarkForm.tmName = row.tmName
      // this.trademarkForm.id = row.id
      // this.trademarkForm.logoUrl = row.logoUrl
      // 清空表单验证结果
      this.$refs.formRef.clearValidate()
    },
    // 显示添加品牌
    showAddTrademark() {
      this.visible = true
      // 清空表单验证结果
      this.$refs.formRef.clearValidate()
      // 清空数据
      // this.trademarkForm.tmName = ''
      // this.trademarkForm.id = undefined
      // this.trademarkForm.logoUrl = ''
      this.trademarkForm = {
        tmName: '',
        logoUrl: ''
      }
    },
    // 添加品牌
    addTrademark() {
      // 验证表单
      this.$refs.formRef.validate(async (valid) => {
        if (valid) {
          // console.log('表单验证通过～')
          // 发送请求，将品牌数据交给服务器保存
          const { id, tmName, logoUrl } = this.trademarkForm
          // 发送请求，添加品牌 --> 添加到服务器。更新的是服务器的数据
          // 客户端是没有数据！
          if (id) {
            await updateTrademark({ id, tmName, logoUrl })
          } else {
            await addTrademark(tmName, logoUrl)
          }

          // 更新客户端（浏览器）的数据
          // 怎么做？在发送一个请求，请求最新的数据展示
          this.getTrademarkList()

          this.$message.success(`${id ? '修改' : '添加'}品牌成功`)
          // 隐藏对话框
          this.visible = false
        }
      })
    },
    // 上传成功的回调
    handleAvatarSuccess(res) {
      // console.log(res)
      // 将响应的图片地址，更新到表单数据中
      this.trademarkForm.logoUrl = res.data
    },
    // 上传之前触发的回调
    beforeAvatarUpload(file) {
      // file 当前上传的文件对象
      // file.type 文件类型 file.size 文件大小
      const isJPGOrPNG = file.type === 'image/jpeg' || file.type === 'image/png'
      const isLt500 = file.size / 1024 <= 500

      if (!isJPGOrPNG) {
        this.$message.error('上传头像图片只能是 JPG 或 PNG 格式!')
      }
      if (!isLt500) {
        this.$message.error('上传头像图片大小不能超过 500KB!')
      }
      // 函数返回值决定能不能上传图片
      return isJPGOrPNG && isLt500
    },
    // 封装一个公共用来发送请求的函数
    async getTrademarkList() {
      const { currentPage, pageSize } = this
      const res = await getTrademarkList(currentPage, pageSize)
      this.trademarkList = res.data.records
      this.total = res.data.total
    },
    // 当每页条数发生变化触发的函数
    handleSizeChange(pageSize) {
      this.pageSize = pageSize
      this.getTrademarkList()
    },
    // 当页码发生变化触发的函数
    handleCurrentChange(currentPage) {
      this.currentPage = currentPage
      this.getTrademarkList()
    }
  }
}
</script>

<style>
.trademark {
  margin: 10px;
}
.trademark-table {
  margin: 10px 0;
}
.el-pagination__sizes,
.el-pagination__total {
  float: right;
}
.trademark-img {
  width: 200px;
  height: 100px;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
.trademark-text {
  color: red;
}
</style>
